/*
 *
 *  * Copyright (C) 2017.
 *  * 用于JAVA项目开发
 *  * 重庆青沃科技有限公司 版权所有
 *  * Copyright (C)  2017.  CqingWo Systems Incorporated. All rights reserved.
 *
 */

package com.link510.aitools.core.helper;

import com.blankj.utilcode.util.StringUtils;
import com.orhanobut.logger.Logger;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;


/**
 * 日期处理工具类
 *
 * @author liuchongke
 * @date Mar 11, 2012
 * @modified by
 * @modified date
 * @see DateHelper
 * @since JDK1.6
 */

public class DateHelper {


    // ~ Static fields/initializers
    // =============================================

    private static String TAG = "DateHelper";


    private static String defaultDatePattern = null;
    private static String timePattern = "HH:mm";
    private static Calendar cale = Calendar.getInstance();
    public static final String TS_FORMAT = DateHelper.getDatePattern() + " HH:mm:ss.S";
    /**
     * 日期格式yyyy-MM字符串常量
     */
    public static final String MONTH_FORMAT = "yyyy-MM";
    /**
     * 日期格式yyyy-MM-dd字符串常量
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 日期格式HH:mm:ss字符串常量
     */
    public static final String HOUR_FORMAT = "HH:mm:ss";
    /**
     * 日期格式yyyy-MM-dd HH:mm:ss字符串常量
     */
    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 某天开始时分秒字符串常量  00:00:00
     */
    public static final String DAY_BEGIN_STRING_HHMMSS = " 00:00:00";
    /**
     * 某天结束时分秒字符串常量  23:59:59
     */
    public static final String DAY_END_STRING_HHMMSS = " 23:59:59";
    public static SimpleDateFormat sdf_date_format = new SimpleDateFormat(DATE_FORMAT);
    public static SimpleDateFormat sdf_hour_format = new SimpleDateFormat(HOUR_FORMAT);
    public static SimpleDateFormat sdf_datetime_format = new SimpleDateFormat(DATETIME_FORMAT);


    // ~ Methods
    // ================================================================

    public DateHelper() {
    }

    /**
     * 获得服务器当前日期及时间，以格式为：yyyy-MM-dd HH:mm:ss的日期字符串形式返回
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getDateTime() {
        try {
            return sdf_datetime_format.format(cale.getTime());
        } catch (Exception ex) {
            Logger.e("DateUtil.getDateTime():", ex);
            return "";
        }
    }

    /**
     * 获得服务器当前日期，以格式为：format 的日期字符串形式返回
     *
     * @return
     * @author wanghong
     * @date 4 24, 2013
     */
    public static String getDate(String pattern) {
        try {
            sdf_date_format.applyPattern(pattern);
            return sdf_date_format.format(cale.getTime());
        } catch (Exception ex) {
            Logger.e("DateUtil.getDate():", ex);
            return "";
        }
    }

    /**
     * 获得服务器当前日期，以格式为：yyyy-MM-dd的日期字符串形式返回
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getDate() {
        try {
            return sdf_date_format.format(cale.getTime());
        } catch (Exception e) {
            Logger.e("DateUtil.getDate():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器当前时间，以格式为：HH:mm:ss的日期字符串形式返回
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getTime() {
        String temp = " ";
        try {
            temp += sdf_hour_format.format(cale.getTime());
            return temp;
        } catch (Exception e) {
            Logger.e("DateUtil.getTime():" + e.getMessage());
            return "";
        }
    }

    /**
     * 统计时开始日期的默认值
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getStartDate() {
        try {
            return getYear() + "-01-01";
        } catch (Exception e) {
            Logger.e("DateUtil.getStartDate():" + e.getMessage());
            return "";
        }
    }

    /**
     * 统计时结束日期的默认值
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getEndDate() {
        try {
            return getDate();
        } catch (Exception e) {
            Logger.e("DateUtil.getEndDate():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器当前日期的年份
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getYear() {
        try {
            return String.valueOf(cale.get(Calendar.YEAR));
        } catch (Exception e) {
            Logger.e("DateUtil.getYear():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器当前日期的月份
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getMonth() {
        try {
            java.text.DecimalFormat df = new java.text.DecimalFormat();
            df.applyPattern("00;00");
            return df.format((cale.get(Calendar.MONTH) + 1));
        } catch (Exception e) {
            Logger.e("DateUtil.getMonth():" + e.getMessage());
            return "";
        }
    }

    /**
     * 获得服务器在当前月中天数
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getDay() {
        try {
            return String.valueOf(cale.get(Calendar.DAY_OF_MONTH));
        } catch (Exception e) {
            Logger.e("DateUtil.getDay():" + e.getMessage());
            return "";
        }
    }

    /**
     * 比较两个日期相差的天数
     *
     * @param date1
     * @param date2
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static int getMargin(String date1, String date2) {
        int margin;
        try {
            ParsePosition pos = new ParsePosition(0);
            ParsePosition pos1 = new ParsePosition(0);
            Date dt1 = sdf_date_format.parse(date1, pos);
            Date dt2 = sdf_date_format.parse(date2, pos1);
            long l = dt1.getTime() - dt2.getTime();
            margin = (int) (l / (24 * 60 * 60 * 1000));
            return margin;
        } catch (Exception e) {
            Logger.e("DateUtil.getMargin():" + e.toString());
            return 0;
        }
    }

    /**
     * 比较两个日期相差的天数
     *
     * @param date1
     * @param date2
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static double getDoubleMargin(String date1, String date2) {
        double margin;
        try {
            ParsePosition pos = new ParsePosition(0);
            ParsePosition pos1 = new ParsePosition(0);
            Date dt1 = sdf_datetime_format.parse(date1, pos);
            Date dt2 = sdf_datetime_format.parse(date2, pos1);
            long l = dt1.getTime() - dt2.getTime();
            margin = (l / (24 * 60 * 60 * 1000.00));
            return margin;
        } catch (Exception e) {
            Logger.e("DateUtil.getMargin():" + e.toString());
            return 0;
        }
    }

    /**
     * 比较两个日期相差的月数
     *
     * @param date1
     * @param date2
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static int getMonthMargin(String date1, String date2) {
        int margin;
        try {
            margin = (Integer.parseInt(date2.substring(0, 4)) - Integer.parseInt(date1.substring(0, 4))) * 12;
            margin += (Integer.parseInt(date2.substring(4, 7).replaceAll("-0",
                    "-")) - Integer.parseInt(date1.substring(4, 7).replaceAll("-0", "-")));
            return margin;
        } catch (Exception e) {
            Logger.e("DateUtil.getMargin():" + e.toString());
            return 0;
        }
    }

    /**
     * 返回日期加X天后的日期
     *
     * @param date
     * @param i
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String addDay(String date, int i) {
        try {
            GregorianCalendar gCal = new GregorianCalendar(
                    Integer.parseInt(date.substring(0, 4)),
                    Integer.parseInt(date.substring(5, 7)) - 1,
                    Integer.parseInt(date.substring(8, 10)));
            gCal.add(GregorianCalendar.DATE, i);
            return sdf_date_format.format(gCal.getTime());
        } catch (Exception e) {
            Logger.e("DateUtil.addDay():" + e.toString());
            return getDate();
        }
    }

    /**
     * 增加天数
     *
     * @param i
     * @return
     */
    public static Date addDay(int i) {
        return addDay(new Date(), i);
    }

    /**
     * 在现有的时间上增加天数
     *
     * @param date
     * @param i
     * @return
     */
    public static Date addDay(Date date, int i) {

        Date today = date;

        Calendar c = Calendar.getInstance();
        c.setTime(today);
        c.add(Calendar.DAY_OF_MONTH, i);// 今天+1天

        Date newdate = c.getTime();

        return newdate;
    }

    /**
     * 获取增加的
     *
     * @param i
     * @return
     */
    public static Timestamp addTsDay(int i) {

        Date newDate = addDay(new Date(), i);
        return getTimestamp(newDate);

    }

    /**
     * 获取增加的
     *
     * @param date
     * @param i
     * @return
     */
    public static Timestamp addTsDay(Date date, int i) {

        Date newDate = addDay(date, i);
        return getTimestamp(newDate);

    }


    /**
     * 返回日期加X月后的日期
     *
     * @param date
     * @param i
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String addMonth(String date, int i) {
        try {
            GregorianCalendar gCal = new GregorianCalendar(
                    Integer.parseInt(date.substring(0, 4)),
                    Integer.parseInt(date.substring(5, 7)) - 1,
                    Integer.parseInt(date.substring(8, 10)));
            gCal.add(GregorianCalendar.MONTH, i);
            return sdf_date_format.format(gCal.getTime());
        } catch (Exception e) {
            Logger.e("DateUtil.addMonth():" + e.toString());
            return getDate();
        }
    }


    /**
     * 增加季度
     *
     * @param date
     * @param i
     * @return
     */
    public static String addQuarter(String date, int i) {

        return addMonth(date, i * 3);
    }

    /**
     * 返回日期加X年后的日期
     *
     * @param date
     * @param i
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String addYear(String date, int i) {
        try {
            GregorianCalendar gCal = new GregorianCalendar(
                    Integer.parseInt(date.substring(0, 4)),
                    Integer.parseInt(date.substring(5, 7)) - 1,
                    Integer.parseInt(date.substring(8, 10)));
            gCal.add(GregorianCalendar.YEAR, i);
            return sdf_date_format.format(gCal.getTime());
        } catch (Exception e) {
            Logger.e("DateUtil.addYear():" + e.toString());
            return "";
        }
    }

    /**
     * 返回某年某月中的最大天
     *
     * @param iyear
     * @param imonth
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static int getMaxDay(int iyear, int imonth) {
        int day = 0;
        try {
            if (imonth == 1 || imonth == 3 || imonth == 5 || imonth == 7
                    || imonth == 8 || imonth == 10 || imonth == 12) {
                day = 31;
            } else if (imonth == 4 || imonth == 6 || imonth == 9 || imonth == 11) {
                day = 30;
            } else if ((0 == (iyear % 4)) && (0 != (iyear % 100)) || (0 == (iyear % 400))) {
                day = 29;
            } else {
                day = 28;
            }
            return day;
        } catch (Exception e) {
            Logger.e("DateUtil.getMonthDay():" + e.toString());
            return 1;
        }
    }

    /**
     * 格式化日期
     *
     * @param orgDate
     * @param Type
     * @param Span
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public String rollDate(String orgDate, int Type, int Span) {
        try {
            String temp = "";
            int iyear, imonth, iday;
            int iPos = 0;
            char seperater = '-';
            if (orgDate == null || orgDate.length() < 6) {
                return "";
            }

            iPos = orgDate.indexOf(seperater);
            if (iPos > 0) {
                iyear = Integer.parseInt(orgDate.substring(0, iPos));
                temp = orgDate.substring(iPos + 1);
            } else {
                iyear = Integer.parseInt(orgDate.substring(0, 4));
                temp = orgDate.substring(4);
            }

            iPos = temp.indexOf(seperater);
            if (iPos > 0) {
                imonth = Integer.parseInt(temp.substring(0, iPos));
                temp = temp.substring(iPos + 1);
            } else {
                imonth = Integer.parseInt(temp.substring(0, 2));
                temp = temp.substring(2);
            }

            imonth--;
            if (imonth < 0 || imonth > 11) {
                imonth = 0;
            }

            iday = Integer.parseInt(temp);
            if (iday < 1 || iday > 31) {
                iday = 1;
            }

            Calendar orgcale = Calendar.getInstance();
            orgcale.set(iyear, imonth, iday);
            temp = rollDate(orgcale, Type, Span);
            return temp;
        } catch (Exception e) {
            return "";
        }
    }

    public static String rollDate(Calendar cal, int Type, int Span) {
        try {
            String temp = "";
            Calendar rolcale;
            rolcale = cal;
            rolcale.add(Type, Span);
            temp = sdf_date_format.format(rolcale.getTime());
            return temp;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 返回默认的日期格式
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static synchronized String getDatePattern() {
        defaultDatePattern = "yyyy-MM-dd";
        return defaultDatePattern;
    }

    /**
     * 将指定日期按默认格式进行格式代化成字符串后输出如：yyyy-MM-dd
     *
     * @param aDate
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static final String getDate(Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (aDate != null) {
            df = new SimpleDateFormat(getDatePattern());
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }

    /**
     * 将原有的日期格式的字符串转换为特定的格式, 如(原有和转换)格式为null, 则使用缺省格式yyyy-MM-dd.
     *
     * @param strValue       value 日期格式的字符串
     * @param strFromPattern fromPattern 原有的日期格式
     * @param strToPattern   toPattern 转换成的日期格式
     * @return String 返回日期字符串
     * @author denghw
     */
    public static String formatDate(String strValue, String strFromPattern, String strToPattern) {
        String strDate = null;
        if (strToPattern == null) {
            strToPattern = "yyyy-MM-dd";
        }
        if (strValue != null) {
            try {
                SimpleDateFormat objFormatter = null;
                if (strFromPattern != null) {
                    objFormatter = new SimpleDateFormat(strFromPattern);
                } else {
                    objFormatter = new SimpleDateFormat("yyyy-MM-dd");
                }
                Date day = objFormatter.parse(strValue);
                objFormatter.applyPattern(strToPattern);
                strDate = objFormatter.format(day);
            } catch (Exception e) {
                return strValue;
            }
            return strDate;
        } else {
            return null;
        }
    }

    /**
     * 取得给定日期的时间字符串，格式为当前默认时间格式
     *
     * @param theTime
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getTimeNow(Date theTime) {
        return getDateTime(timePattern, theTime);
    }

    /**
     * 取得当前时间的Calendar日历对象
     *
     * @return
     * @throws ParseException
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public Calendar getToday() throws ParseException {
        Date today = new Date();
        SimpleDateFormat df = new SimpleDateFormat(getDatePattern());
        String todayAsString = df.format(today);
        Calendar cal = new GregorianCalendar();
        cal.setTime(convertStringToDate(todayAsString));
        return cal;
    }

    /**
     * 将日期类转换成指定格式的字符串形式
     *
     * @param aMask
     * @param aDate
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static final String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate == null) {
            Logger.e("aDate is null!");
        } else {
            df = new SimpleDateFormat(aMask);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }

    /**
     * 将指定的日期转换成默认格式的字符串形式
     *
     * @param aDate
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static final String convertDateToString(Date aDate) {
        return getDateTime(getDatePattern(), aDate);
    }

    /**
     * 将日期字符串按指定格式转换成日期类型
     *
     * @param aMask   指定的日期格式，如:yyyy-MM-dd
     * @param strDate 待转换的日期字符串
     * @return
     * @throws ParseException
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static final Date convertStringToDate(String aMask, String strDate)
            throws ParseException {


        Date date = null;

        try {
            SimpleDateFormat df = null;
            df = new SimpleDateFormat(aMask);
            date = df.parse(strDate);
        } catch (ParseException pe) {
            throw pe;
        }
        return (date);
    }

    /**
     * 将日期字符串按默认格式转换成日期类型
     *
     * @param strDate
     * @return
     * @throws ParseException
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static Date convertStringToDate(String strDate)
            throws ParseException {
        Date aDate = null;

        try {

            Logger.e("converting date with pattern: " + getDatePattern());

            aDate = convertStringToDate(getDatePattern(), strDate);
        } catch (ParseException pe) {
            Logger.e("Could not convert '" + strDate + "' to a date, throwing exception");
            throw new ParseException(pe.getMessage(), pe.getErrorOffset());
        }
        return aDate;
    }

    /**
     * 返回一个JAVA简单类型的日期字符串
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static String getSimpleDateFormat() {
        SimpleDateFormat formatter = new SimpleDateFormat();
        String NDateTime = formatter.format(new Date());
        return NDateTime;
    }

    /**
     * 将指定字符串格式的日期与当前时间比较
     *
     * @param strDate 需要比较时间
     * @return <p>
     * int code
     * <ul>
     * <li>-1 当前时间 < 比较时间 </li>
     * <li> 0 当前时间 = 比较时间 </li>
     * <li>>=1当前时间 > 比较时间 </li>
     * </ul>
     * </p>
     * @author DYLAN
     * @date Feb 17, 2012
     */
    public static int compareToCurTime(String strDate) {
        if (StringUtils.isEmpty(strDate)) {
            return -1;
        }
        Date curTime = cale.getTime();
        String strCurTime = null;
        try {
            strCurTime = sdf_datetime_format.format(curTime);
        } catch (Exception e) {
            Logger.e("[Could not format '" + strDate + "' to a date, throwing exception:" + e.getLocalizedMessage() + "]");

        }
        if (StringUtils.isTrimEmpty(strCurTime)) {
            return -1;
        }


        return strCurTime.compareTo(strDate);
    }


    /**
     * 为查询日期添加最小时间
     *
     * @param param 目标类型Date
     * @return
     */
    public static Date addStartTime(Date param) {

        Date date = param;

        try {
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            return date;
        } catch (Exception ex) {
            return date;
        }

    }

    /**
     * 增加秒
     *
     * @param date   目标类型Date
     * @param second 转换参数Date
     * @return
     */
    public static Date addSecond(Date date, int second) {

        try {
            cale.setTime(date);
            cale.add(Calendar.SECOND, second);
            return cale.getTime();
        } catch (Exception ex) {
            return date;
        }
    }

    /**
     * 为查询日期添加最大时间
     *
     * @param param 转换参数Date
     * @return
     */
    public static Date addEndTime(Date param) {
        Date date = param;
        try {
            date.setHours(23);
            date.setMinutes(59);
            date.setSeconds(0);
            return date;
        } catch (Exception ex) {
            return date;
        }
    }

    /**
     * 返回系统现在年份中指定月份的天数
     *
     * @param month 月份
     * @return 指定月的总天数
     */
    @SuppressWarnings("deprecation")
    public static String getMonthLastDay(int month) {
        Date date = new Date();
        int[][] day = {{0, 30, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
        int year = date.getYear() + 1900;
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return day[1][month] + "";
        } else {
            return day[0][month] + "";
        }
    }

    /**
     * 返回指定年份中指定月份的天数
     *
     * @param year  年份
     * @param month 月份
     * @return 指定月的总天数
     */
    public static String getMonthLastDay(int year, int month) {
        int[][] day = {{0, 30, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return day[1][month] + "";
        } else {
            return day[0][month] + "";
        }
    }

    /**
     * 判断是平年还是闰年
     *
     * @param year
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    public static boolean isLeapyear(int year) {
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 取得当前时间的日戳
     *
     * @return
     * @author dylan_xu
     * @date Mar 11, 2012
     */
    @SuppressWarnings("deprecation")
    public static Timestamp getTimestamp() {

        Date date = new Date();
        Timestamp timestamp = new Timestamp(date.getTime());
        return timestamp;
    }

    /**
     * 取得指定时间的日戳
     *
     * @return
     */
    public static Timestamp getTimestamp(String s) {

        Date date;
        try {
            s = s.trim();
            s = s.replace("/", "-");

            date = convertStringToDate("yyyy-MM-dd hh:mm:ss", s);

        } catch (ParseException e) {
            date = new Date();
        }

        return getTimestamp(date);
    }


    public static Timestamp getTodayTimestamp() {

        Date date = new Date();
        try {

            String s = sdf_date_format.format(date);

            date = sdf_date_format.parse(s);


        } catch (ParseException e) {
            date = new Date();
        }

        return getTimestamp(date);
    }


    /**
     * 取得指定时间的日戳
     *
     * @return
     */
    @SuppressWarnings("deprecation")
    public static Timestamp getTimestamp(Date date) {
        Timestamp timestamp;
        try {

            timestamp = new Timestamp(date.getTime());

        } catch (Exception ex) {

            date = new Date();
            timestamp = new Timestamp(date.getTime());
        }


        return timestamp;
    }

    /**
     * 当前日期向后n天(n可取负值,表示向前)
     *
     * @param
     * @return
     * @leizong
     * @2014-7-31
     */
    public static String nextDay(String date, int n, String format) throws Exception {
        // 后一天
        DateFormat fmt = new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        cal.setTime(fmt.parse(date));
        // 转成毫秒  增加一天  再转回来
        cal.setTimeInMillis(cal.getTimeInMillis() + n * 24 * 60 * 60 * 1000);
        String tm_next = fmt.format(cal.getTime());
        return tm_next;
    }

    /**
     * 昨天8点
     */
    public static String yesterDay8() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(cal.getTimeInMillis() - 1 * 24 * 60 * 60 * 1000);

        DateFormat fmt = new SimpleDateFormat(DATE_FORMAT);
        String tm_next = fmt.format(cal.getTime());
        return tm_next + " 08:00";
    }


}
